package com.yanqu.road.server.gameplayer.module.activity.harps.confirm;

import com.yanqu.road.entity.activity.harps.*;
import com.yanqu.road.entity.common.CommonConfirm;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.pb.activity.harps.Harps;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.harps.HarpsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.harps.HarpsMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HarpsPlayOneConfirm extends CommonConfirm {
    private HarpsUserData userData;
    private GamePlayer player;
    private Map<Integer, Map<Integer, HarpsRewardInfo>> rewardInfoMap;      // 奖池
    private HarpsConfigSync config;                                         // 配置
    private Property reduce;                                                // 要消耗的道具
    private int floor;                                                      // 层数
    HarpsRewardInfo harpsRewardInfo;                                        // 中奖信息
    Harps.HarpsPlayResp.Builder builder = Harps.HarpsPlayResp.newBuilder(); // 回复消息
    private boolean isTen = false;                                          // 是否是十连抽
    private boolean isBigReward;                                            // 是否大奖

    public HarpsPlayOneConfirm(HarpsUserData userData, GamePlayer player, Map<Integer, Map<Integer, HarpsRewardInfo>> rewardInfoMap) {
        this.userData = userData;
        this.player = player;
        this.rewardInfoMap = rewardInfoMap;
        this.config = HarpsMgr.getConfig();
        if (this.userData == null) {
            player.getModule(HarpsModule.class).initSystem();
        }
    }

    @Override
    public boolean check() {
        if (config == null) {
            builder.setRet(GameErrorCode.E_HARPS_CONFIG_ERROR);
            return false;
        }
        int mountainItemId = config.getParamConfig().getMountainItemId();
        reduce = new Property(mountainItemId, userData.getPerDrawReduceCount());
        if (!player.getModule(CurrencyModule.class).currencyIsEnough(reduce)) {
            builder.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
            return false;
        }
        if (isTen && userData.getScore() < config.getParamConfig().getMountainTenPlayLimit()) {
            builder.setRet(GameErrorCode.E_HARPS_TEN_SCORE_LIMIT);
            return false;
        }
        if (rewardInfoMap.get(config.getHighestFloor()).size() != 3) {
            builder.setRet(GameErrorCode.E_HARPS_CHOOSE_REWARD_NULL);
            return false;
        }
        if (needReset()) {
            builder.setRet(GameErrorCode.E_HARPS_NEED_RESET);
            return false;
        }
        return true;
    }

    @Override
    public boolean tryOperate() {
        // 随机颜色
        eHarpsColorEnum color = eHarpsColorEnum.Color_Reset;
        floor = userData.getFloor();
        if (userData.getFloor() != config.getHighestFloor()) {
            List<List<Integer>> mountainFloorPro = config.getParamConfig().getMountainFloorPro();
            List<Integer> list = new ArrayList<>(mountainFloorPro.get(userData.getFloor() - 1));
            if (list == null || list.isEmpty() || list.get(0) != userData.getFloor()) {
                builder.setRet(GameErrorCode.E_HARPS_CONFIG_ERROR);
                return false;
            }
            list.remove(0);
            int index = HarpsMgr.getRandomHelper().getSafeRandomIndexByWeight(list);
            color = eHarpsColorEnum.forValue(index);
            if (index < eHarpsColorEnum.Color_TouMing.getValue() || index > eHarpsColorEnum.Color_Pink.getValue() || color == null) {
                builder.setRet(GameErrorCode.E_HARPS_RANDOM_ERROR);
                return false;
            }

            if (userData.getPlayNum() >= config.getParamConfig().getMountainMaxDraw()) {
                // 如果演奏次数达到对应的保底，则只会上升
                color = eHarpsColorEnum.Color_Gold;
            }
        }

        // 随机道具
        List<Integer> weightList = new ArrayList<>();
        List<HarpsRewardInfo> rewardInfos = new ArrayList<>();
        Map<Integer, HarpsRewardInfo> rewardMap = rewardInfoMap.get(floor);
        if (rewardMap == null) {
            builder.setRet(GameErrorCode.E_HARPS_NO_REWARD_INDEX);
            return false;
        }
        for (HarpsRewardInfo rewardInfo : rewardMap.values()) {
            // 新增优化，颜色不在作为上下移动依据，道具按照表中配置的权重进行随机
            //if (rewardInfo.getColor() == color.getValue() || rewardInfo.getFloor() == config.getHighestFloor()) {
                HarpsMountConfig mountConfig = config.getMountConfigMap().get(rewardInfo.getId());
                weightList.add(rewardInfo.getIsGetReward() ? 0 : mountConfig.getWeight());
                rewardInfos.add(rewardInfo);
            //}
        }
        int indexReward = HarpsMgr.getRandomHelper().getSafeRandomIndexByWeight(weightList);
        harpsRewardInfo = rewardInfos.get(indexReward);
        if (harpsRewardInfo == null) {
            builder.setRet(GameErrorCode.E_HARPS_RANDOM_ERROR);
            return false;
        }

        if (color.getValue() == eHarpsColorEnum.Color_Gold.getValue()) {
            floor = floor + 1;
        }else if (color.getValue() == eHarpsColorEnum.Color_Pink.getValue()) {
            floor = floor - 1;
        } else if (color.getValue() == eHarpsColorEnum.Color_Reset.getValue()) {
            if (floor == config.getHighestFloor()) {
                isBigReward = true;
                floor = 1;
            }
        }

        // 扣道具
        if (!player.getModule(CurrencyModule.class).removeCurrency(reduce, eLogMoneyType.Harps, eLogMoneyType.HarpsPlay)) {
            builder.setRet(GameErrorCode.E_HARPS_USE_ITEM_ERROR);
            return false;
        }
        return true;
    }

    @Override
    public boolean confirm() {
        // 给奖励
        HarpsMountConfig mountConfig = config.getMountConfigMap().get(harpsRewardInfo.getId());
        if (mountConfig == null) {
            builder.setRet(GameErrorCode.E_HARPS_NO_REWARD_CONFIG);
            return false;
        }

        userData.setScore(userData.getScore() + config.getParamConfig().getMountainScoreGain() * userData.getPerDrawReduceCount());
        userData.setScoreUpdateTime(System.currentTimeMillis());
        userData.setPlayNum(isBigReward ? 0 : userData.getPlayNum() + 1);
        userData.setFloor(floor);
        userData.setPlaySum(userData.getPlaySum() + 1);
        harpsRewardInfo.setIsGetReward(isBigReward);
        harpsRewardInfo.setRemainChooseNum(isBigReward && harpsRewardInfo.getRemainChooseNum() != config.getRemainChooseNumNoLimit() ? harpsRewardInfo.getRemainChooseNum() - 1 : harpsRewardInfo.getRemainChooseNum());
        if (isBigReward) {
            tryResetHighestFloor();
            tryAddUnlockNum(harpsRewardInfo.getSeat());
        }
        String reward = isBigReward ? config.getHighestReward(harpsRewardInfo.getId(), harpsRewardInfo.getNo()) : mountConfig.getAward();
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.Harps, eLogMoneyType.HarpsPlayReward);
        player.getModule(CurrencyModule.class)
                .addCurrency(config.getParamConfig().getScoreItem() + "=" + config.getParamConfig().getMountainScoreGain() * userData.getPerDrawReduceCount(),eLogMoneyType.Harps,eLogMoneyType.HarpsPlayReward);

        // 设置回包内容
        builder.setRet(0);
        builder.setPlayer(player.getModule(HarpsModule.class).parsePlayerInfo());
        Harps.HarpsGainRewardInfo.Builder builderReward = Harps.HarpsGainRewardInfo.newBuilder();
        builderReward.setFloor(harpsRewardInfo.getFloor());
        builderReward.setSeat(harpsRewardInfo.getSeat());
        builder.addRewardInfo(builderReward);
        builder.setReward(reward);
        builder.setScore(config.getParamConfig().getMountainScoreGain() * userData.getPerDrawReduceCount());

        // 更新成就和排行榜
        player.notifyListener(eGamePlayerEventType.HarpsScoreRank.getValue(), (long)userData.getScore());
        player.notifyListener(eGamePlayerEventType.HarpsPlaySum.getValue(), (long)userData.getPlaySum());
        return true;
    }

    @Override
    public void onCheck(boolean succeed) {
        if (!succeed && !isTen) {
            player.sendPacket(ClientProtocol.U_HARPS_PLAY, builder);
        }
    }

    @Override
    public void onSucceed() {
        if (!isTen) {
            player.sendPacket(ClientProtocol.U_HARPS_PLAY, builder);
        }
    }

    @Override
    public void onFailed() {
        if (!isTen) {
            player.sendPacket(ClientProtocol.U_HARPS_PLAY, builder);
        }
    }

    public void setTen(boolean ten) {
        isTen = ten;
    }

    public int getFloor() {
        return floor;
    }

    public Harps.HarpsPlayResp.Builder getBuilder() {
        return builder;
    }

    private void tryResetHighestFloor() {
        if (needReset()) {
            player.getModule(HarpsModule.class).resetChooseReward();
            userData.setFloor(1);
            userData.setRound(userData.getRound() + 1);
            userData.setPerDrawReduceCount(config.getParamConfig().getMountainDrawNumByRound(userData.getRound()));
        }
    }

    private void tryAddUnlockNum(int seat) {
        if (!isBigReward) {
            return;
        }
        player.getModule(HarpsModule.class).tryAddUnlockNum(seat);
    }

    private boolean needReset() {
        boolean needReset = true;
        for (HarpsRewardInfo rewardInfo : rewardInfoMap.get(config.getHighestFloor()).values()) {
            if (!rewardInfo.getIsGetReward()) {
                needReset = false;
                break;
            }
        }
        return needReset;
    }

    public boolean isBigReward() {
        return isBigReward;
    }
}
